package main

//MARK 方法就是多了一个结构体的入参的 的 函数

import (
	"fmt"
	"math"
)

type Vertex struct {
	X, Y float64
}

func (v Vertex) Abs() float64 {//MARK 和普通函数比 就多了一个 (v Vertex) 这里是传副本 
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
	v := Vertex{3, 4}
	fmt.Println(v.Abs())

	noStructMethod()
	pointers()
}

//MARK 用指针接受者 好处 1:能改里面的值 2:高效   , 在结构体里面又有结构体的时候 都该是指针接收
func (v *Vertex) Scale(f float64) { //MARK 指针接收这 就是在对象本身上改
	v.X = v.X * f
	v.Y = v.Y * f
}
func pointers() {
	fmt.Println("=====================指针接受者======================")
	v := Vertex{3, 4}
	v.Scale(10)//MARK 虽然方法接受的是指针这样 值调也行 会自动转, 反过来也成立
	fmt.Println(v.Abs())
}

type MyFloat float64 //MARK 给这个加方法
func (f MyFloat) Abs() float64 {//MARK 类型必须定义在同个包内
	if f < 0 {
		return float64(-f)
	}
	return float64(f)
}

func noStructMethod() {
	fmt.Println("=====================非结构体类型 方法======================")
	f := MyFloat(-math.Sqrt2)
	fmt.Println(f.Abs())
}

